\section{The Community Module}
\label{sec:community}

One of the aspects of iSquirrel that makes it more fun and enjoyable from other recommender systems is that it is community driven. It relies on the importance of a community and promotes making friends with common interests online. Currently iSquirrel supports adding friends, showing to the user the pages his\slash her friends liked, measuring how close two users are based on their profile and recommending friends. 

Having said that, one is not expected to use iSquirrel to make friends. While that can certainly be done, it's not the main use of the application. Generating good recommendations is what should attract users, as this area of the project has seen the biggest effort. However, iSquirrel comes as a community driven product, therefore our users are encouraged to add friends whenever they feel like doing so.

\subsection{Keeping interests public} 
All users of iSquirrel are allowed to have a public set of interests. The idea is that users can view what other users are interested in, and then add them as friends. Someone's interests can be viewed when searching iSquirrel for users. They also appear under the name of the suggested friends, as shown in Figure \ref{friend_suggestions}. They serve as a hint about whether one could possibly make good friends with another user.

\subsection{Connect with Facebook}
During registration time, or even at a later stage, one is given the opportunity to \emph{connect with Facebook}. If a user takes this option, they are requested to login to their Facebook account. If the user connects to Facebook successfully, we can then retrieve their details (including name, surname, picture etc) using the JavaScript API\cite{FB}. We also retrieve their Facebook friends, and in that case we proceed to a user match, giving all users who use iSquirrel and are friends with the user in question on Facebook. We then simply mark them as friends in our system.

A user is not required to connect with Facebook upon registration. If they want they can simply enter their details and start using iSquirrel. That is, connecting with Facebook or not does not affect the quality of service the user gets, in any way. 

\subsection{Searching for friends}

Our application provides a very powerful way for finding friends. One can search for other people by first name, last name, user-name or even a particular interest that the other person may have listed. When a search request is made, the \emph{FindFriends.java} servlet is called. As shown in Listing~\ref{user_search}, this servlet performs a linear search on all the registered users in the system. For each user it checks the search keywords for matches, one by one. The users with matches are put in a list, and are then sorted based on the number of matches. The ones with the most matches appear first in the search results.

%\newpage
\lstset{language=Java}
\lstset{backgroundcolor=\color{white}}
\lstset{tabsize=2} 
\lstset{keywordstyle=\color{red}\bfseries}
\begin{lstlisting}[frame=tb, caption=Searching for users, label=user_search]
[...] 		
  for (User u : allUsers) {	
    int count; 
    if ( (count = countMatches(u,searchTokens)) > 0) {
      results.put(u, new Pair(count, i));
    }
    i++;
  }
[...]
public static int countMatches(User user, String[] tokens) {
  int matches = 0;
  for (String token : tokens) {
    if (!token.trim().equals("")) {
      if (user.getFirstName().toUpperCase().contains(token.toUpperCase()) ||
	    user.getLastName().toUpperCase().contains(token.toUpperCase()) ||
	    user.getUsername().toUpperCase().contains(token.toUpperCase()) ||
	    user.getInterests_labels().toString().contains(token.toUpperCase())
	    ) {
	      matches++;
      }
    }
  }
  return matches;
}
\end{lstlisting}

\begin{figure}[H] 
\begin{center}
\includegraphics[width=4in]{resources/search_results.png}
\caption{ Searching for users with ``car" in their interests }
\label{search_results}
\end{center}
\end{figure}

\subsection{What your network likes}

A user can also see the most popular pages among their friends or the whole of the network. The former can be accessed by clicking on \emph{What your friends like} and the latter on \emph{What other people like}. In both cases the result is a sorted list of pages giving the number of people that liked the page as well as a ranking, stating how relevant is the page according to your profile.

Our team debated on whether we should present just a list of the most frequently liked pages, or if we should have a more clever algorithm that compares each \textit{page} with the user's profile and decides which would be a better match. The advantage of the second method is that we could receive potentially better results, but it was adding more complexity to our project. 

If we wanted to take the second path, we should implement an algorithm that would take as input a list of pages and one user. For each page in the list, it would have to receive the \emph{page information}\footnote[1]{
\emph{Page information} is a list of \emph{properties} that describe the content of a Wikipedia article. The can be retrieved by querying DBpedia.} from DBpedia and then compare them with the profile of the user. We should then have some kind of points assignment to each page that shows how close it is with the user. Finally the ones with the most points should appear first in the recommendations. We deemed this solution unnecessarily complex and slow given the external requests to the DBPedia endpoint.

We finally decided to use a modification of the \emph{Collaborative Filtering} algorithm described in \cite{CollInt} by combining it with the \emph{Profile Comparison} algorithm described in Section \ref{sec:profile-comparison-algorithm}. We measure the frequency of each liked page but instead of sorting on the frequency we calculate a \textit{relevance factor} for each like and sort by that. This allows to have the most relevant results first, even if they are not the most frequently liked. This method can work for recommending pages from friends as well as from the whole network.

The \textit{relevance factor} of each ``like'' is calculated using the Profile Comparison algorithm, which gives us a measure on how close two user profiles are. The closer they are, the more probable it is that the "liked" pages of two users will be interesting for each other. The relevance factor of a liked page for a user, is the sum of the profile comparison measure of all the users that liked that page, shown in Listing~\ref{friend_algo}.

\lstset{language=Java}
\lstset{backgroundcolor=\color{white}} 
\lstset{keywordstyle=\color{red}\bfseries}
\lstset{tabsize=2}
\begin{lstlisting}[frame=tb, caption=Calculating the relevance factor, label= friend_algo]
for every "like" L of a friend do:
  comparison_value := compare(user,friend)
    if L has already been encountered:
      L.frequency++ 
      L.relevance_factor += comparison_value
    else:
      L.frequency = 1
      encountered_likes.add(L)
      L.relevance_factor = comparison_value
end loop
\end{lstlisting}


\subsection{Suggesting friends}
\label{sec:profile-comparison-algorithm}
Our system has enough information about its users, to be able to know whether two people match. In that case we present to the user the potentially new friend of theirs, and vice versa, once they click on \emph{Find Friends}.

\begin{figure}[H] 
\begin{center}
\includegraphics[width=2in]{resources/friend_suggestions.png}
\caption{ Friend suggestions }
\label{friend_suggestions}
\end{center}
\end{figure}

Figure \ref{friend_suggestions} appears on the right-hand side of the screen. A user can add another user by clicking on \emph{Add to friends}. If they decide in the future that they no longer want to be friends with someone, they can simply click on \emph{Remove from friends}, at the left-hand side of the screen, where we display the friends of the user.

These suggestions are generated based on how similar the \emph{Dynamic Profiles} of two users are. The similarity measure is calculated by the \emph{Profile Comparison Algorithm} described below.

\subsubsection{Profile Comparison}

The \emph{Profile Comparison} algorithm is a linear algorithm based on the \emph{Minimum-Comparison Merging} algorithm described in \cite{ArtOfCP} and in this context is used to measure the similarity of two users profiles. Similarity is measured by the properties that appear in both profiles, and is represented as a real number, between zero and one. As demonstrated in Listing~\ref{lst:compare}, common properties with higher frequency are going to produce a bigger returned number, thus giving a higher rating for similarity. This decision relies on the fact that properties with higher frequency should normally matter more to a user, therefore they are more important when deciding which users to recommend. The first two lines of code, in Listing~\ref{lst:compare}, return an iterator to a list of the properties of the users, sorted by the attribute of the properties and its value. 
\\
\lstset{language=Java}
\lstset{backgroundcolor=\color{white}}
%\lstset{numbers=left, numberstyle=\tiny, stepnumber=1, numbersep=5pt} 
\lstset{keywordstyle=\color{red}\bfseries\emph}
\begin{lstlisting}[frame=tb, caption=Profile Comparison Algorithm: Calculating how close two user's profiles are, label=lst:compare]
Property p1 = user1_properties.next();
Property p2 = user2_properties.next();

//Iterate over the list of properties until one of them runs
//out of elements 

while (true) {
	try {
	
		if (p1.compareTo(p2) == 0) {
			
			sum += difference(p1.getFrequency(),p2.getFrequency());
			p1 = itr1.next();
			p2 = itr2.next();
			
		} else if (p1.compareTo(p2) < 0) {
			p1 = itr1.next();
		} else {
			p2 = itr2.next();
		}
	
	} catch (NoSuchElementException e) {
		break;
	}
}

return 2 * sum / (sumOfFreqs(propertyList1) + sumOfFreqs(propertyList2));


\end{lstlisting}

The \emph{difference()} function returns the smallest frequency, plus the absolute value of the difference of the frequencies, divided by two, as shown in Listing~\ref{lst:dif}. This calculation is done in this way, so that when a user with properties that have low frequencies, matches another user whose respective properties have high frequencies, doesn't receive a rating which is proportional to the frequency of the properties of the other user.

 Instead, the user gets a ``matching rating" witch is closer to the frequency of their own properties, leaving room for equal ratings when comparing with other users who might have the same properties but with a smaller frequency. Finally, \emph{sumOfFreqs()} returns the sum of the frequencies of all the properties in the profile of a user.
\newpage
\lstset{language=Java}
\lstset{backgroundcolor=\color{white}}
%\lstset{numbers=left, numberstyle=\tiny, stepnumber=1, numbersep=5pt} 
\lstset{keywordstyle=\color{red}\bfseries\emph}
\begin{lstlisting}[frame=tb, caption=The difference function, label=lst:dif]
	public static double difference(long freq1, long freq2) {
		return Math.min(freq1, freq2) + (Math.abs(freq1-freq2)/2);
	}
	
	public static long sumOfFreqs(List<Property> propertyList) {
		long sum = 0;
		for (Property p : propertyList) {
			sum += p.getFrequency();
		}
		return sum;
	}
\end{lstlisting}